#pragma once
#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib, "d3dx9.lib")
#include <dxerr.h>
#pragma comment(lib, "dxerr.lib")
#include <sstream>
#include "Objects.h"
#include "Input.h"

const unsigned g_numMeshes = 3;
const unsigned g_numTextures = 3;
enum eMeshType;
enum Handles // This enum is for the Handler array for easy setting of the handles
{
	TECHNIQUE,		WVP,			WM,
	EYEPOSITION,	LIGHTPOS,		AMBLIGHT,
	SPECLIGHT,		DIFLIGHT,		LIGHTATTEN,
	TEXTURE,		TEXTURESAMPLER,
	MAXSIZE
};
struct TexturePack			// small struct containing a pointer to the texture and its image info
{
	LPDIRECT3DTEXTURE9	lpTexture;
	D3DXIMAGE_INFO		imgInfo;

	bool operator==(TexturePack comparee)
	{
		if(this->lpTexture == comparee.lpTexture)
		{
			return true;
		}

		return false;
	}
};
struct d3dCamera
{
	D3DXVECTOR3	eyePos;		// position of the camera in world space
	D3DXVECTOR3 lookAt;		// point that the camera is facing
	D3DXVECTOR3	upVec;		// which way is up; should be a normalized vector
};
// singleton class used to draw to the screen using DirectX 9
class Graphics
{
private:

	Graphics();									// private constructor, making this a singleton
	IDirect3DDevice9*		m_pD3DDevice;		// the main d3d interface
	HWND					m_hWnd;				// a 'personal' copy of the hWnd that Renderer can use
	bool					m_bWindowed;		// true = windowed; false = fullscreen
	float					m_fScreenWidth;		// screen height given by hWnd
	float					m_fScreenHeight;	// screen width given by hWnd
	D3DPRESENT_PARAMETERS	m_D3Dpp;			// present parameter
	d3dCamera				m_Camera;
	bool					m_bIsOriented;		// whether the camera should zoom in or out
	D3DLIGHT9				m_DefaultLight;		

	ID3DXEffect*			m_pEffect;			//The effect file

	/*///////////////////////////////////////////
	//
	//All of these D3DXHandles are use
	//
	/*//////////////////////////////////////////
	D3DXHANDLE*				m_Handles[MAXSIZE]; // An array that will be holding all the variables that have to be sent into the effect file.

	// camera matrices
	D3DXMATRIX				m_matView;
	D3DXMATRIX				m_matPerspective;

	// for drawing
	D3DXMATRIX				m_matTrans;
	D3DXMATRIX				m_matRot;
	D3DXMATRIX				m_matScale;
	D3DXMATRIX				m_matWorld;

	//For drawing font
	ID3DXFont*				m_pD3DFont;			// font used to display on the screen
	RECT					m_rLeftInst;		//Positions the left instructions
	RECT					m_rRighInst;		//Positions the right instructions
	RECT					m_rCreditCrd;		//Credit Coords will go here
	RECT					m_rCameraCrd;		//Camera Coords will go here
	RECT					m_rPlayerCrd;		//Player Coords will go here
	std::ostringstream		m_Printer;			//Holds value to be printed

	// array of available meshes to use
	ID3DXMesh*				m_pMeshLibrary[g_numMeshes];
	char*					m_cszMeshNames[g_numMeshes];

	// array of textures
	TexturePack				m_tpTexLibrary[g_numTextures];
	char*					m_cszTexNames[g_numTextures];

	D3DMATERIAL9			m_dmDefaultMaterial;

	//private functions only used by Graphics
	bool SetupDevice(HWND hWnd);
	bool SetupFont();
	bool SetupTextures();
	bool SetupMeshes();
	bool SetupLight();
	void LoadMeshFile		(const char* cszXFile, ID3DXMesh*& pMesh);	
	//void LoadTextureFile	(const char* cszTextureFile, IDirect3DTexture9*& pTexture); //Load from an image


	/*Subsets of Render*/
	void RenderFont(D3DXVECTOR3 playerPos);


public:
	~Graphics();									// destructor

	inline static Graphics* Engine()				// return the address of the singleton
	{static Graphics g; return &g;}

	bool Init(HWND hWnd);

	void CheckDevice();
	void SetCameraFocus(D3DXVECTOR3 pos);
	void SetCameraPos(D3DXVECTOR3 pos);
	void SetLightPos(D3DXVECTOR3 pos);
	ID3DXMesh* getMeshByIndex(unsigned index);
	LPDIRECT3DTEXTURE9 getTextureByIndex(unsigned index);
	bool Render(DrawList& drawlist);
	void Update();

};
